from django.conf import settings
from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen
import logging
import json

from .exceptions import QQAPIEXCEPTION


# 日志记录器
logger = logging.getLogger('django')


class OAuthQQ(object):
    """提供qq登录地址的类"""

    def __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):
        self.client_id = client_id or settings.QQ_CLIENT_ID # app_id
        self.client_secret = client_secret or settings.QQ_CLIENT_SECRET # app_key
        self.redirect_uri = redirect_uri or settings.QQ_REDIRECT_URI
        self.state = state or settings.QQ_STATE  # 用于保存登录成功后的跳转页面路径

    def get_qq_login_url(self):
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': self.state,
            'scope': 'get_user_info',
        }

        # https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=&redirect_uri=&state=&scope=get_user_info
        url = 'https://graph.qq.com/oauth2.0/authorize?' + urlencode(params)
        return url

    def get_access_token(self, code):
        """
        通过code,向QQ服务器获取access_token
        :param code: 调用凭据
        :return: access_token
        """

        # 准备访问参数
        params = {
            'grant_type':'authorization_code',
            'client_id':self.client_id,
            'client_secret':self.client_secret,
            'code':code,
            'redirect_uri':self.redirect_uri
        }

        # 获取access_token的url
        url = 'https://graph.qq.com/oauth2.0/token?' + urlencode(params)

        try:
            # 向url发送get请求,获取返回值
            response_data = urlopen(url)
            # 提取access_token
            response_str = response_data.read().decode()
            response_dict = parse_qs(response_str)
            access_token = response_dict.get('access_token', None)
        except Exception as e:
            logger.error(e)
            # 封装工具类时，出错抛出异常，不要自己解决，谁调用谁解决
            raise QQAPIEXCEPTION('调用QQ接口获取access_token失败')

        return access_token[0]

    def get_openid(self, access_token):
        """
        获取用户的openid
        :param access_token: qq提供的access_token
        :return: open_id
        """
        url = 'https://graph.qq.com/oauth2.0/me?access_token=' + access_token
        response = urlopen(url)
        response_data = response.read().decode()
        try:
            # 返回的数据 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )\n;
            data = json.loads(response_data[10:-4])
        except Exception:
            data = parse_qs(response_data)
            logger.error('code=%s msg=%s' % (data.get('code'), data.get('msg')))
            raise QQAPIEXCEPTION('调用QQ接口获取openid失败')

        # 取出opendid
        openid = data.get('openid', None)
        return openid
